<?php

/**
 * 数组的助手类
 */
class Helper_Array
{
	/**
	 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
	 * keys to arrays rather than overwriting the value in the first array with the duplicate
	 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
	 * this happens (documented behavior):
	 *
	 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
	 *     => array('key' => array('org value', 'new value'));
	 *
	 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
	 * Matching keys' values in the second array overwrite those in the first array, as is the
	 * case with array_merge, i.e.:
	 *
	 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
	 *     => array('key' => array('new value'));
	 *
	 * Parameters are passed by reference, though only for performance reasons. They're not
	 * altered by this method.
	 *
	 * @param array $array1
	 * @param array $array2
	 * @return array
	 * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
	 * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
	 */
	public static function arrayMergeRecursiveDistinct( array &$array1 , array &$array2 )
	{
		$merged = $array1;

		foreach( $array2 as $key => &$value )
		{
			if( is_array( $value ) && isset( $merged[$key] ) && is_array( $merged[$key] ) )
			{
				$merged[$key] = Helper_Array::arrayMergeRecursiveDistinct( $merged[$key] , $value );
			}
			else
			{
				$merged[$key] = $value;
			}
		}

		return $merged;
	}
	
	/**
	 * 格式化输出
	 * 根据二维数组字段格式化输出
	 * 
	 * @param array $array
	 * @param string $index
	 * @author tom
	 */
	public static function format( $array , $index = 'id' )
	{
		$newArray = array();
		foreach ( $array as $item )
		{
			$newArray[ $item[ $index ] ] = $item;
		}
		return $newArray;
	}
	
	/**
	 * 获取不重复的二维数组字段列表
	 * 
	 * @param array $array
	 * @param string $index
	 * @author tom
	 */
	public static function getUniqueIds( $array , $index = 'id' )
	{
		$ids = array();
		foreach( $array as $item )
		{
			if( !in_array( $item[ $index ] , $ids))
			{
				$ids[] = $item[ $index ];
			}
		}
		
		return $ids;
		
	}
	
	/**
	 * 给数组添加前缀或者后缀
	 * 
	 * @param array $ids
	 * @param string $postfix	//后缀
	 * @param string $prefix	//前缀
	 */
	public static function addString( $ids , $postfix = '' , $prefix = '' )
	{
		$new = array();
		foreach( $ids as $id )
		{
			$new[] = "{$prefix}{$id}{$postfix}";
		}
		
		return $new;
		
	}
	
	/**
	 * 
	 * 根据指定的键对数组进行排序
	 * @param array $array
	 * @param string $keyname
	 * @param string $dir
	 */
	public static function sortByCol( $array , $keyname , $dir = SORT_DESC )
	{
		return self::sortByMultiCols( $array , array( $keyname => $dir ) );
	}

	/**
	* 将一个二维数组按照多个列进行排序，类似 SQL 语句中的 ORDER BY
	*
	* 用法：
	* @code php
	* $rows = Helper_Array::sortByMultiCols($rows, array(
	*           'parent' => SORT_ASC, 
	*           'name' => SORT_DESC,
	* ));
	* @endcode
	*
	* @param array $rowset 要排序的数组
	* @param array $args 排序的键
	*
	* @return array 排序后的数组
	*/
	public static function sortByMultiCols( $rowset, $args )
	{
		$sortArray = array();
		$sortRule = '';
		foreach ( $args as $sortField => $sortDir ) 
		{
			foreach ( $rowset as $offset => $row ) 
			{
				$sortArray[$sortField][$offset] = $row[$sortField];
			}
			
			$sortRule .= '$sortArray[\'' . $sortField . '\'], ' . $sortDir . ', ';
		}
		
		if ( empty($sortArray) || empty($sortRule ) )
			return $rowset;
			
		eval( 'array_multisort(' . $sortRule . '$rowset);' );
		return $rowset;
	}
	
	/**
	 * 过滤数组中不需要的字段。如果某个字段的值是数组，请慎用此方法，特别在$recursive = true的时候
	 * @param array $array				要过滤的数组
	 * @param array $requiredFields		需要的字段
	 * @param boolean $recursive		是否递归过滤$array中的数组，仅适用于以数组为元素的列表
	 */
	public static function filterFields( &$array , &$requiredFields , $recursive = true )
	{
		foreach( $array as $field => &$value )
		{
			if( $recursive && is_array( $value ) )
			{
				self::filterFields( $value , $requiredFields , $recursive );
			}
			else
			{
				if( ! in_array( $field , $requiredFields, true ) )
				{
					unset( $array[ $field ] );
				}
			}
		}
	}
    
    /**
     * 二维数组去掉重复值，不保留键
     * 
     * @param array $array2D
     * @return array
     */
    public static function array_unique_fb( $array2D )
    {
        if( empty( $array2D ) )
        {
            return array();
        }
        
        //保存键
        $keys = array_keys( $array2D[0] );
        
        $result = array();
        foreach( $array2D as $v )
        {
            $v = join( ',' , $v );              //降维,也可以用implode,将一维数组转换为用逗号连接的字符串
            $temp[] = $v;
        }

        $temp = array_unique( $temp );          //去掉重复的字符串,也就是重复的一维数组
        foreach( $temp as $k => $v )
        {
            $data = explode( ',' , $v );    //再将拆开的数组重新组装
            for( $i = 0; $i < count( $keys ); $i++ )
            {
                $result[$k][ $keys[$i] ] = $data[$i];
            }
        }
        
        return $result;
    }
}